<?php
/**
 * 信息操作类
 * User: zhc
 * Date: 2019/10/24
 * Time: 10:16
 */

namespace app\swoole\service;

use app\model\ChatLog;
use app\model\Kefu;
use app\user\service\ChatService;
use app\user\service\KefuService;
use app\user\service\UserService;
use app\swoole\command\Chat;
use Swoole\Coroutine\Redis;
use  think\Db;
use  think\Exception;
use  think\facade\Log;
use  Logic\KefuLogic;
use  exception\LogicException;
use  Logic\ServiceLogic;
use exception\BaseException;
use Logic\QueueLogic;
use Logic\Visitor;
use Logic\ChatLogLogic;

class Event
{
    /**
     * 认证token 不存在直接关闭/存在返回用户信息
     * @param $fd
     * @param $token
     * @param $server
     * @return bool|mixed
     * @author dgc<453342213@qq.com>
     * createTime:2020/8/31 15:16
     */
    public static function checkToken($fd, $data, $server)
    {
        $str = '';
        $redis = redisConnect();
        switch ($data['source']) {
            case 'user':
                $str = 'user_';
                break;
            case 'kefu':
                $str = 'kf_';
                break;
            default:
                $json = self::returnJson(200, '请重新登录', [], 'login_out');
                $server->push($fd, $json);
                $redis->hDel('online', $fd);
                $server->close($fd);
                return false;
                break;
        }
        $userInfo = $redis->hGet('login_info', $str . $data['token']);
        //用户登录后才会在redis里面缓存
        if (!$userInfo) {
            $json = self::returnJson(200, '请重新登录', [], 'login_out');
            $server->push($fd, $json);
            $redis->hDel('online', $fd);
            $server->close($fd);
            return false;
        }
        return json_decode($userInfo, true);
    }

    /**
     * 客服登录
     * @param $fd
     * @param $userInfo
     * @param $data
     * @param $server
     * @return false|string
     * @author dgc<453342213@qq.com>
     * createTime:2020/8/31 15:16
     */
    public static function kefuConnection($fd, $userInfo, $data, $server)
    {
        try {
            //更新客服状态
            $param = [
                'login_status' => 1,
                'fd' => $fd
            ];
            KefuService::saveKefu($userInfo['id'], $param);
            //设置客服信息
            redisHset('online', $fd, 'KF_' . $userInfo['id']);
            redisHset('kefu', $userInfo['id'], $fd);
            KefuService::saveChat(['kefu_id' => $userInfo['id']], ['kefu_client_id' => $fd]);
            return self::returnJson(200, '客服上线成功', [], 'kefu_online');
        } catch (\Exception $e) {
            throw new \Exception('客服上线错误', 401);
        }
    }

    /**
     * 用户登录
     * @param $fd  客户端标识
     * @param $data  请求数据
     */
    public static function userConnection($fd, $userInfo, $data, $server)
    {
        try {
            $ip = getClientIp();
            //添加或者修改会话
            $chatData = [
                'reception_status' => 0,//等待状态
                'client_id' => $fd,
                'ip' => $ip,
                'user_id' => $userInfo['id']
            ];
            UserService::saveChat(['user_id' => $userInfo['id']], $chatData);
            //用户信息更新
            $data = [
                'id' => $userInfo['id'],
                'login_ip' => $ip,
                'login_status' => 1
            ];
            UserService::updateUser($data);
            //设置设置信息
            redisHset('online', $fd, $userInfo['id']);
            //设置设置信息
            redisHset('user', $userInfo['id'], $fd);
            return self::returnJson(200, '上线成功', [], 'user_online');
        } catch (BaseException $e) {
            throw new BaseException('上线错误', 401);
        }
    }

    /**
     * 用户连接客服
     * @param $fd
     * @param $userInfo
     * @param $data
     * @param $server
     * @return false|string
     * @author dgc<453342213@qq.com>
     * createTime:2020/9/3 14:26
     */
    public static function userToKefu($fd, $userInfo, $data, $server)
    {
        //查询会话
        $chatInfo = \app\model\Chat::where('user_id', $userInfo['id'])->find();
        if (is_null($chatInfo)) {
            return self::returnJson(400, '异常操作', [], '');
        }
        //匹配客服
        $kefuInfo = ChatService::matchingChatKefu($chatInfo);
        Log::record('分配客服数据：' . json_encode($kefuInfo));
        // 更新会话
        $chatInfo->reception_status = 1;//更改连接状态
        $chatInfo->kefu_id = $kefuInfo['id'];
        $chatInfo->kefu_client_id = $kefuInfo['fd'];
        $chatInfo->save();
        //客服在线发送通知 判断加上redis的客服信息
        if ($kefuInfo['login_status'] == 1) {
            $resut = self::returnJson(200, '用户上线', ['chat_id' => $chatInfo['id'], 'login_status' => 1], 'user_online');
            $server->push($kefuInfo['fd'], $resut);
        }
        return self::returnJson(200, '连接客服成功', $kefuInfo, 'user_to_kefu');
    }

    /**
     * 聊天
     * @param $fd  客户端标识
     * @param $data  请求数据
     */
    public static function message($fd, $userInfo, $data, $server)
    {
        Log::record('聊天信息[' . json_encode($data) . ']');
        $uid = redisHget('online', $fd);
        try {
            $message = [
                'send_type' => $data['send_type'],
                'content' => $data['content'],
                'to_id' => $data['to_id'],
                'from_id' => $userInfo['id'],
                'chat_id' => $data['chat_id'],
            ];
            switch ($data['send_type']) {
                case 'image':
                    $msg = '[图片]';
                    break;
                case 'voice':
                    $msg = '[语音]';
                    break;
                default:
                    $msg = mb_substr($data['content'], 0, 20,'utf-8');
                    break;
            }
            //消息入库
            $chatModel = ChatService::addLog($message);
            //修改会话内容
            $message['c_time'] = date('Y-m-d H:i:s');
            $message['log_id'] = $chatModel->id;
            $message['md5id'] = $data['md5id'] ?? '';
            if (strstr($uid, "KF_") !== false) {//客服发用户
                UserService::saveChat(['id' => $data['chat_id']], ['kefu_last_msg' => $msg, 'kefu_last_time' => time()]);
                $user_fd = redisHget('user', $data['to_id']);
                if ($server->exist((int)$user_fd) == true) {
                    $resut = self::returnJson(200, '来新信息了', $message, 'get_message');
                    $server->push((int)$user_fd, $resut);
                }
            } else {  //用户发给客服
                UserService::saveChat(['id' => $data['chat_id']], ['user_last_msg' => $msg, 'user_last_time' => time()]);
                $kefu_fd = redisHget('kefu', $data['to_id']);
                if ($server->exist((int)$kefu_fd) == true) {
                    $resut = self::returnJson(200, '来新信息了', $message, 'get_message');
                    $server->push((int)$kefu_fd, $resut);
                }
            }
        } catch (BaseException $e) {
            return self::returnJson(400, '消息发送失败', $data['message'], 'message');
        }
        return self::returnJson(200, '信息发送成功', $message, 'message');

    }

    /**
     * 断开连接
     * @param $fd  客户端标识
     * @param $data  请求数据
     */
    public static function disconnect($fd, $server)
    {
        $uid = redisHget('online', $fd);
        if (!$uid) {
            return false;
        }
        if (strstr($uid, "KF_") !== false) { //客服退出
            $uid = ltrim($uid, 'KF_');
            //修改状态
            KefuService::saveKefu(['id' => $uid], ['login_status' => 2]);
            redisHdel('online', $fd);
            redisHdel('kefu', $uid);
        } else {//用户退出
            redisHdel('online', $fd);
            redisHdel('user', $uid);
            UserService::updateUser(['id' => $uid, 'login_status' => 2]);
            $chatInfo = UserService::saveChat(['user_id' => $uid], ['reception_status' => 2]);
            if (isset($chatInfo['kefu_client_id']) && $server->exist((int)$chatInfo['kefu_client_id']) == true) {
                $resut = self::returnJson(200, '用户离线', ['login_status' => 2, 'chat_id' => $chatInfo['id']], 'user_online');
                $server->push($chatInfo['kefu_client_id'], $resut);
            }
        }
        return true;
    }

    /**
     * 返回json
     * @param int $code
     * @param string $msg
     * @param array $data
     * @return false|string
     */
    public static function returnJson($code = 200, $msg = "操作成功", $data = [], $type = 'heartbeat')
    {
        return json_encode([
            'code' => $code,
            'msg' => $msg,
            'data' => $data,
            'type' => $type
        ], JSON_UNESCAPED_UNICODE);

    }
}